package stardust.product.platform.webc.spi.servlet;


import java.io.IOException;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import stardust.product.platform.webc.RenderForward;
import stardust.product.platform.webc.RenderHandle;
import stardust.product.platform.webc.WebcConfig;
import stardust.product.platform.webc.WebcException;
import stardust.product.platform.webc.WebcRequestHandler;
import stardust.product.platform.webc.WebcResourceReference;


public class JspRenderer implements RenderHandle
{

  public void render(WebcRequestHandler request, WebcResourceReference reference, String uri, RenderForward forward)
  {
    ServletWebcRequestHandler req = (ServletWebcRequestHandler) request;
    RequestDispatcher requestDispatcher;
    String returnPath;
    
    returnPath = forward.getResultPath();

    if (returnPath == null || returnPath.isEmpty())
    {
      return;
    }

    try
    {
      returnPath = returnPath.indexOf(':') == -1 ? "forward:" + returnPath : returnPath;

      Map<String, Object> context = req.getUtils();
      context.put("result", forward.getResult());
      req.getRequest().setAttribute("webc", context);

      if (returnPath.indexOf(':') != -1)
      {
        String jumpType = returnPath.substring(0, returnPath.indexOf(':')).trim();
        String jumpUri = returnPath.substring(returnPath.indexOf(':') + 1).trim();

        if (!jumpType.equalsIgnoreCase("redirect"))
        {
          /*
           * 计算追加前导和后缀。
           */
          String prefix = request.getWebcContext().getConfig().getParameter().get(WebcConfig.CFG_PATH_PREFIX);
          String suffix = request.getWebcContext().getConfig().getParameter().get(WebcConfig.CFG_PATH_SUFFIX);

          if (prefix != null)
          {
            prefix = prefix.replace('\\', '/');
            prefix = prefix.endsWith("/") ? prefix.substring(0, prefix.length() - 1) : prefix;
            jumpUri = jumpUri.startsWith("/") ? jumpUri : "/" + jumpUri;
            jumpUri = prefix + jumpUri;
          }
          if (suffix != null)
          {
            suffix = suffix.replace('\\', '/');
            jumpUri = jumpUri + suffix;
          }
        }

        if (jumpType.equalsIgnoreCase("redirect"))
        {
          /*
           * 计算本地重定向。
           */
          if (jumpUri.startsWith("$"))
          {
            jumpUri = req.getRequest().getContextPath() + jumpUri.substring(1);
          }
          
          /*
           * 执行HTTP转移指令。
           */
          req.getResponse().sendRedirect(jumpUri);
          return;
        }
        else if (jumpType.equalsIgnoreCase("forward"))
        {
          /*
           * 执行容器内转移。
           */
          requestDispatcher = req.getRequest().getRequestDispatcher(jumpUri);
          requestDispatcher.forward(req.getRequest(), req.getResponse());
          return;
        }
        else if (jumpType.equalsIgnoreCase("include"))
        {
          /*
           * 执行容器内包含。
           */
          requestDispatcher = req.getRequest().getRequestDispatcher(jumpUri);
          requestDispatcher.include(req.getRequest(), req.getResponse());
          return;
        }
      }

      /*
       * 默认执行容器内转移。
       */
      requestDispatcher = req.getRequest().getRequestDispatcher(returnPath);
      requestDispatcher.forward(req.getRequest(), req.getResponse());
    }
    catch (ServletException e)
    {
      throw new WebcException("访问资源[" + uri + " -> " + reference.getUri() + "]时发生错误，调用处理程序成功，但执行渲染失败。", e);
    }
    catch (IOException e)
    {
      throw new WebcException("访问资源[" + uri + " -> " + reference.getUri() + "]时发生错误，调用处理程序成功，但执行渲染失败。", e);
    }
  }

}
